<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>

        // function fn1(a){
        //     console.log(a)
        // }
        // var arg1=3;
        // fn1(arg1);
// 输出结果为3，arg1在函数fn1里，等同于把arg1的值带进去，得到fn1(3)，再运行函数输出结果为3



        // var  a=3;
        // var b=a;
        // b++;
        // console.log(a,b)
        // 输出结果为3,4。 a属于非引用类型，就是基础类型，给赋值之后，自身不会发生改变


            //  function fn1(o){
            //         o.a=10;
            //     }
                // var obj={a:1};
                // fn1(obj);
                // console.log(obj);
                // 将变量带进去之后，o={a:1},o.a就是对引用地址进行改变，但对象都是o，所以obj的值也是10


                // var o1={a:1};
                // var o2=o1;
                // o2.a=10;(重新给o2换了引用地址)
                // console.log(o1); 
                // o1的引用地址没有发生改变，所以o1为{a:1}

                // 对比上一种可以看出，在考虑这类题时，首先看是更改了引用对象的属性还是引用对象的值
                // 1.更改引用对象的属性，生成新的地址，原地址没有发生改变
                // 2.更改引用对象的值，就是对引用对象的地址进行改变，两者用同一地址


            // function fn1(a,b,c,d=10){
            // console.log(a,b,c,d)
            // }
            // fn1(1,2,3);
            // 输出结果为1,2,3,10  ES6中形参可以设置初始值


            // function fn1(d=10,a,b,c,){
            // console.log(d,a,b,c)
            // }
            // fn1(undefined,1,2,3);

            // 对比上一个可以发现，想把设置初始值得放在前面显示，函数中对应的设置为undefined

                
            // 回调
            // function fn1(fn){
            //     fn();
            // }
            // function fn2(){

            // }
            // fn1(fn2);
            // 执行fn1时，就是将参数fn2带入进fn1的函数中，就会将fn赋值给fn2，fn与fn2是引用关系，执行fn时，
            // 就是执行fn2，这种写法叫做回调


                // function fn1(fn){
                //     fn();
                // }
                // fn1(function(){

                // })

                // 执行fn1时，就是将匿名函数传入，执行fn 就意味着执行function

                    
            //  function fn1(fn){
            //     for(var i=0;i<10;i++){
            //         fn(i);
            //     }
            // }

            // function fn2(a){
            //     console.log(a);
            // }
            // fn1(fn2);

            // 输出结果是0到9 fn调用时，其中的i的数值在发生变化，而执行fn就意味着执行fn2，
            // 所以a=i,那么i的值就是a的值


//         function fn1(fn){
//             for(var i=0;i<10;i++){
//                 fn(i);
//             }
//         }

//         fn1(function(a){
//             console.log(a);
//         })

// function(a)为匿名函数，但效果与上方相同


        // ES6
        // 传入不定数量的参数时都会被放在arg这个数组中   ...arg 必须放在形参的最后
        // function fn1(...arg){
        //     console.log(arg);
        // }
        // fn1(1,2,3,4,5);
        // 输出结果为一个数组


        
        
        
        
        
        // arguments 实参列表
       
        // function fn1(){
        //     var s=0;
        //     for(var i=0;i<arguments.length;i++){
        //         s+=arguments[i];
        //     }
        //     return s;
        // }

        // var sum=fn1(1,2,3,4,5,6);
        // console.log(sum);

// fn1执行时，arguments.length， return 返回值给s，求和后就是sum的值
//  arguments.length在函数内是当前函数传入的实参数量 
// console.log(fn1.length);通过获取函数的length可以获取到函数的形参数量

         // console.log(arguments.callee);//就是当前函数
        //     console.log(arguments.callee.name);//就是当前的名字
        //     console.log(arguments.callee.caller);//调用当前函数的上下文函数




// 匿名递归：
        // function fn1(fn){
        //     fn(0);
        // }

        // fn1(function(a){
        //     a++;
        //     console.log(a);
        //     if(a>3) return;
        //     arguments.callee(a);
        // })

// fn1执行时调用fn1,a的值为0，进入循环后，通过arguments.callee再次调用fn1
// 当a大于3时，停止循环











    </script>
</body>
</html>